package ws

import (
	"encoding/json"
	"fmt"
	"log"
	"loghub/cache"
	"loghub/common"
	"loghub/db"
	"loghub/model"
	"loghub/model/request"

	"github.com/gorilla/websocket"
	"github.com/kataras/iris/v12"
)

// RegisterWsLogServer 注册websocket日志服务
func RegisterWsLogServer(app *iris.Application) {
	// 注册websocket
	var upgrader = websocket.Upgrader{}

	app.Get("/ws/log", func(ctx iris.Context) {
		// 可以在这里验证身份, 判断用户是否登录
		var r = ctx.Request()
		var w = ctx.ResponseWriter()
		ch := make(chan string)
		go func() {
			c, err := upgrader.Upgrade(w, r, nil)
			ch <- fmt.Sprintf("客户端%s正在连接...", c.RemoteAddr().String())
			if err != nil {
				log.Print("upgrade:", err)
				return
			}
			defer c.Close()
			for {
				_, message, err := c.ReadMessage()
				if err != nil {
					log.Println("read:", err)
					break
				}
				var requestData = request.WsRequestData{}
				err = json.Unmarshal(message, &requestData)
				if err != nil {
					log.Println("error data:", message, err)
					continue
				}

				log.Printf("recv: %s", message)

				if requestData.Path == "logdata" {
					var logDetailData model.LogDetailData
					common.SetStructFieldByJSONName(&logDetailData, requestData.Data.(map[string]interface{}))

					projectInfo, err := cache.GetProjectInfo(logDetailData.ProjectID)
					if err != nil {
						log.Println(err)
						c.WriteJSON(model.ResponseData{State: false, Message: "获取项目失败", Error: err.Error(), HTTPCode: 400})
						return
					}
					if projectInfo.ProjectID != logDetailData.ProjectID || len(logDetailData.ProjectID) < 32 {
						c.WriteJSON(model.ResponseData{State: false, Message: "获取项目失败", HTTPCode: 400})
						return
					}

					if len(logDetailData.TraceID) < 32 {
						c.WriteJSON(model.ResponseData{State: false, Message: "TraceID参数错误", HTTPCode: 400})
						continue
					}
					// 写入日志到数据库中
					var sql = "insert into log_detail_data values ('%s','%s','%s','%s','%s','%d','%s','%s','%s','%s','%d','%s','%s','%s','%s','%s')"
					var querystring = fmt.Sprintf(sql,
						logDetailData.TraceID,
						logDetailData.ProjectID,
						logDetailData.LogLevel,
						logDetailData.LogTitle,
						logDetailData.LogContent,
						logDetailData.HTTPStatusCode,
						logDetailData.StackTrace,
						logDetailData.ErrorType,
						logDetailData.AssemblyName,
						logDetailData.ProcessName,
						logDetailData.ProcessID,
						logDetailData.PackageName,
						logDetailData.FunctionName,
						logDetailData.ClientIP,
						logDetailData.Remark,
						logDetailData.CreateTime.Format("2006-01-02 15:04:05"))
					exexResult, err := db.ExecSQL(querystring)
					if err != nil {
						log.Println(err)
						c.WriteJSON(model.ResponseData{State: false, Message: "创建失败", Data: logDetailData, Error: err.Error(), HTTPCode: 500})
						return
					}
					fmt.Println(exexResult)
					c.WriteJSON(model.ResponseData{State: true, Message: "写入日志成功"})
				} else if requestData.Path == "logtrace" {
					var requestTraceData = requestData.Data.(map[string]interface{})
					var logTraceData request.LogTraceRequest
					common.SetStructFieldByJSONName(&logTraceData, requestTraceData)

					projectInfo, err := cache.GetProjectInfo(logTraceData.ProjectID)
					if err != nil {
						log.Println(err)
						c.WriteJSON(model.ResponseData{State: false, Message: "获取项目失败", Error: err.Error(), HTTPCode: 400})
						return
					}
					if projectInfo.ProjectID != logTraceData.ProjectID || len(logTraceData.ProjectID) < 32 {
						c.WriteJSON(model.ResponseData{State: false, Message: "获取项目失败", HTTPCode: 400})
						return
					}

					if len(logTraceData.TraceID) < 32 || len(logTraceData.RPCTraceID) < 32 {
						c.WriteJSON(model.ResponseData{State: false, Message: "TraceID或者RPCTraceID参数错误", HTTPCode: 400})
						return
					}

					// 写入日志到数据库中
					var sql = "insert into log_trace_info values ('%s','%s','%s','%s','%s','%s','%s','%s','%d','%s','%s','%s','%s','%s','%s')"
					var querystring = fmt.Sprintf(sql,
						logTraceData.RPCTraceID,
						logTraceData.TraceID,
						logTraceData.LogTitle,
						logTraceData.LogContent,
						logTraceData.StackTrace,
						logTraceData.ErrorType,
						logTraceData.AssemblyName,
						logTraceData.ProcessName,
						logTraceData.ProcessID,
						logTraceData.PackageName,
						logTraceData.FunctionName,
						logTraceData.ClientIP,
						logTraceData.OSName,
						logTraceData.Remark,
						logTraceData.CreateTime.Format("2006-01-02 15:04:05"))
					exexResult, err := db.ExecSQL(querystring)
					if err != nil {
						log.Println(err)
						c.WriteJSON(model.ResponseData{State: false, Message: "创建失败", Data: logTraceData, Error: err.Error(), HTTPCode: 500})
						return
					}
					fmt.Println(exexResult)
					c.WriteJSON(model.ResponseData{State: true, Message: "写入日志成功"})
				}
			}
			log.Println("Sockets 关闭, 客户端下线了.")
		}()
		log.Println(<-ch)
	})

	app.Get("/echo", func(ctx iris.Context) {
		// 可以在这里验证身份, 判断用户是否登录
		var r = ctx.Request()
		var w = ctx.ResponseWriter()

		c, err := upgrader.Upgrade(w, r, nil)
		if err != nil {
			log.Print("upgrade:", err)
			return
		}
		defer c.Close()
		for {
			mt, message, err := c.ReadMessage()
			if err != nil {
				log.Println("read:", err)
				break
			}
			log.Printf("recv: %s", message)
			err = c.WriteMessage(mt, message)
			if err != nil {
				log.Println("write:", err)
				break
			}
		}
		log.Println("Sockets 关闭, 客户端下线了.")
	})
}
